package com.gangwangchina.android.contactlib;

import java.util.Iterator;
import java.util.Map;

import com.gangwangchina.android.contactlib.model.DataElement;
import com.gangwangchina.android.contactlib.model.Person;
import com.gangwangchina.android.contactlib.model.PersonContact;

import android.content.OperationApplicationException;
import android.net.Uri;
import android.os.RemoteException;


public interface ContactsInterface {

	/**
	 * NO_ID should be used when objects are created and are not yet stored in the database
	 */
	public static final long NO_ID = 0;
	
	/**
	 * An object with an INVALID_ID is an object that was not successfully stored in the databse
	 */
	public static final long INVALID_ID = -1;
	

	/**
	 * Adds a PersonContact to the contacts
	 * @param pc
	 * @return the id of the PersonContact in the database
	 * @throws RemoteException
	 * @throws OperationApplicationException
	 */
	public long add(PersonContact pc) throws RemoteException,
			OperationApplicationException;

	/**
	 * Adds a data element to the database
	 * @param data
	 * @return the id of the DataElement in the database
	 * @throws RemoteException
	 * @throws OperationApplicationException
	 */
	public long add(DataElement data) throws RemoteException,
			OperationApplicationException;

	/**
	 * Deletes a person and all of its PersonContacts and their DataElements from the database
	 * @param person
	 * @return true if the operation succeded
	 * @throws RemoteException
	 * @throws OperationApplicationException
	 */
	public boolean delete(Person person) throws RemoteException,
			OperationApplicationException;

	/**
	 * Deletes a PersonContact and all of its DataElements from the database
	 * @param pc
	 * @return true if the operation succeded
	 * @throws RemoteException
	 * @throws OperationApplicationException
	 */
	public boolean delete(PersonContact pc) throws RemoteException,
			OperationApplicationException;

	/**
	 * Deletes a DataElement from the database
	 * @param data
	 * @return true if the operation succeded
	 * @throws RemoteException
	 * @throws OperationApplicationException
	 */
	public boolean delete(DataElement data) throws RemoteException,
			OperationApplicationException;

	/**
	 * Retrieves the list of all the people in your contact list
	 * @return
	 */
	public Iterator<Person> list();
	
	/**
	 * Retrieves the list of all the contacts
	 * @return
	 */
	public Iterator<PersonContact> listContacts();

	/**
	 * Updates a person and all of its PersonContacts and their DataElements
	 * @param person
	 * @return
	 * @throws OperationApplicationException 
	 * @throws RemoteException 
	 */
	public boolean update(Person person) throws RemoteException, OperationApplicationException;

	/**
	 * Updates a PersonContact and all of it DataElements
	 * @param pc
	 * @return
	 * @throws OperationApplicationException 
	 * @throws RemoteException 
	 */
	public boolean update(PersonContact pc) throws RemoteException, OperationApplicationException;

	/**
	 * Updates a DataElement
	 * @param data
	 * @return true if the operation is successful
	 * @throws OperationApplicationException 
	 * @throws RemoteException 
	 */
	public boolean update(DataElement data) throws RemoteException, OperationApplicationException;
	
	/**
	 * Updates a DataElement in the database
	 * @param id the id number for that element
	 * @param params a map of properties-values to be updated
	 * @return true if the operation is successful
	 * @throws OperationApplicationException 
	 * @throws RemoteException 
	 */
	public boolean updateData(long id, Map<String, String> params) throws RemoteException, OperationApplicationException;

	/**
	 * Updates a PersonContact in the databse
	 * @param id the id number fot that contact
	 * @param params a map of properties-values to be updated
	 * @return true if the operation is successful
	 * @throws RemoteException
	 * @throws OperationApplicationException
	 */
	public boolean updatePersonContact(long id, Map<String, String> params) throws RemoteException, OperationApplicationException;

	/**
	 * Retrieves a person from the database
	 * @param id the id of the person
	 * @return
	 */
	public Person getPersonById(long id);

	/**
	 * Retrieves a PersonContact from the database
	 * @param id the id of the PersonContact
	 * @return
	 */
	public PersonContact getPersonContactById(long id);
	
	/**
	 * An optimized method to look up for contacts according to their telephone number
	 * @param number
	 * @return a list of Person matching the telephone number
	 */
	public Iterator<Person> telephoneSearch(String number);
	
	/**
	 * A full search
	 * @param dataType the data type that should be looked into
	 * @param value the value to be matched
	 * @return a list of Person meeting the criteria
	 */
	public Iterator<Person> fullSearch(String dataType, String value);
	
	/**
	 * A filter search, where it is only needed to specify the begining of the value
	 * @param filterUri depends on the datatype, basically, it should be ClassName.FILTER_SEARCH
	 * @param value the value to be matched
	 * @return a list of Person meeting the criteria
	 */
	public Iterator<Person> filterSearch(Uri filterUri, String value);
	
	/**
	 * A complex search according to several criteria
	 * @param params a map of datatypes-values that represents the criteria of the search
	 * @return a list of Person meeting the criteria
	 */
	public Iterator<Person> complexSearch(Map<String,String> params);

}